<script setup lang="ts">
import { computed, nextTick, onMounted, reactive, ref } from 'vue'
import FullCalendar from '@fullcalendar/vue3'
import resourceTimelinePlugin from '@fullcalendar/resource-timeline'
import { Message } from '@arco-design/web-vue'
import { useRouter } from 'vue-router'
import axios from 'axios'
import dayjs from 'dayjs'
import {
  getMeetingRoomData,
  getMeetingRoomList,
  getSitebuildinglist
} from '@/apis/meet/meetingRoom'
import type { getMeetingRoomDataQuery } from '@/apis/meet/meetingRoom'
import { meetScheduledmeet } from '@/apis/meet/component'
import meetingMessage from '@/views/meet/meetCalendar/component/meetingMessage.vue'
import meetingService from '@/views/meet/meetCalendar/component/meetingService.vue'
import meetingSignln from '@/views/meet/meetCalendar/component/meetingSignIn.vue'
import meetingTemplate from '@/views/meet/meetCalendar/component/meetingTemplate.vue'
import { getFactoryList } from '@/apis/organization/factory'
import { getCurrentUserInfo } from '@/apis/system/user'

const initialUserInfo = ref(null) // 新增：当前用户信息
const newMeetingModalVisible = ref(false) // 新建会议弹窗变量
const screenImageModalVisible = ref(false) // 门口屏图片弹窗变量
const meetingMessageValue = ref(false) // 子组件事件变量
const newMeetingTabsKeyValue = ref()
const meetingType = ref(0) // 会议类型 0 线下 1 线上
const showMeetingMessage = ref(true)
// 新建会议表单提交参数
const formQuery = ref({
  meetingConfig: {
    userId: '', // 预定人userId
    subject: '', // 会议主题
    startTime: '', // 开始时间
    length: '', // 持续时间
    mediaTypes: '', // 媒体类型
    meetRoomId: '', // 会议室id
    meetType: '', // 会议类型 0 线下 1 线上
    signEndTime: '', // 会议签到结束时间
    enableSignOut: '', // 是否启用会议签退，0关闭，1开启
    signInBeforeMinutes: '', //	会议开始前多少分钟可以签到
    signOutMinutesAfterSignIn: '', // 会议签到多少分钟后才能签退
    signOutAfterEndMinutes: '', // 会议结束多少分钟后不能签退
    backgroundImageURL: null, // 图片链接
    updateMethod: '', // 更新方式：restoreDefault（恢复默认图片），single（单个图片更新），空（不更新）
    inviteScreen: 0, // 新增字段，默认不邀请
    templateUrl: '', // 会务模板URL
    confConfigInfo: {
      isGuestFreePwd: null, // 来宾是否免密
      callInRestriction: null, // 允许加入的会议范围 0：无限制 1：企业内部用户
      guestPwd: '', // 来宾密码
      enableWaitingRoom: null // 是否开启等候室
    },
    cycleParams: {
      startDate: '', // 开始日期 2025-02-25
      endDate: '', // 结束日期
      cycle: '', // 循环类型 Day，Week，Month
      interval: null, // 间隔时间 Integer
      point: [] // 周期点（如每周的哪些天）
    },
    attendees: [
      {
        accountId: '', // 与会者userid
        appId: ''
      }
    ]
  },
  serviceList: []
})
const router = useRouter()
// arco.design分页器参数
const page = reactive({
  current: 1, // 当前页码
  pageSize: 10, // 每页数量
  total: 0, // 总数据量
  showTotal: true, // 是否显示总数
  showJumper: true // 是否显示页码跳转
})
const meetingRoomList = ref() // 会议室列表
const meetEventList = ref() // 会议日程列表
const todayDate = ref() // 今天日期
const sitebuildingValue = ref() // 办公楼id
const factoryValue = ref<number>(254) // 厂区id
const floorValue = ref() // 楼层id
// 查询会议列表的参数
const tableQuery = ref<any>({
  meetType: '',
  conferenceState: '',
  searchDate: ''
})
/**
 * 会议室占有情况请求参数
 */
const meetingRoomDataQuery = ref<getMeetingRoomDataQuery>({
  factoryId: 0,
  type: 'day',
  date: ''
})
const treeData = ref() // 办公楼选择框数据
const fullCalendar = ref('resourceTimelineDay') // 创建模板引用
// 存储 API 实例
const calendarApi = ref()
const calendarOptions = ref({
  plugins: [resourceTimelinePlugin],
  headerToolbar: {
    left: '',
    center: 'title',
    right: ''
  },
  customButtons: {},
  height: 400,
  schedulerLicenseKey: 'CC-Attribution-NonCommercial-NoDerivatives',
  buttonText: {
    today: '今天',
    resourceTimelineMonth: '月',
    week: '周',
    resourceTimelineDay: '日'
  },
  aspectRatio: 1.5,
  editable: false,
  eventStartEditable: false,
  eventDurationEditable: false,
  droppable: false,
  eventDragStart: () => false,
  eventDragStop: () => false,
  initialView: 'resourceTimelineDay',
  resources: meetingRoomList,
  events: meetEventList,
  eventClick: null,
  locale: 'zh-cn',
  handleWindowResize: true,
  timeFormat: 'H:mm',
  slotMinTime: '00:00:00',
  slotMaxTime: '24:00:00',
  allDaySlot: false,
  slotDuration: '01:00:00',
  resourceAreaWidth: '200px',
  stickyHeaderDates: true,
  resourcesInitiallyExpanded: true,
  firstDay: 1,
  nowIndicator: false,
  resourceAreaColumns: [
    {
      field: 'title',
      headerContent: '会议室',
      width: '200px'
    }
  ],
  views: {
    resourceTimelineDay: {
      type: 'resourceTimeline',
      duration: { days: 1 },
      slotDuration: '01:00:00',
      slotMinWidth: 30, // 调小最小宽度，便于短会议显示
      slotLabelFormat: [
        { hour: '2-digit', minute: '2-digit', hour12: false }
      ]
    },
    resourceTimelineWeek: {
      type: 'resourceTimeline',
      duration: { days: 7 },
      slotDuration: '06:00:00', // 6小时一格
      slotMinWidth: 30, // 调小最小宽度，便于短会议显示
      slotLabelFormat: [
        { weekday: 'short', month: '2-digit', day: '2-digit' }, // 周五 04-12
        { hour: '2-digit', minute: '2-digit', hour12: false } // 06:00
      ]
    },
    resourceTimelineMonth: {
      type: 'resourceTimeline',
      duration: { months: 1 },
      slotDuration: { days: 1 }, // 一天一格
      slotMinWidth: 20, // 月视图更小
      slotLabelFormat: {
        day: 'numeric' // 只显示数字，不显示"日"字
      },
      slotLabelContent: (arg) => {
        // 自定义标签内容，只返回日期数字
        return arg.date.getDate().toString()
      }
    }
  },
  resourceTimelineDay: {
    slotMinWidth: 30
  },
  resourceTimelineWeek: {
    slotMinWidth: 30
  },
  resourceTimelineMonth: {
    slotMinWidth: 20
  },
  expandRows: true,
  initialDate: new Date(),
  resourceAreaHeaderClass: 'fc-resource-area-header',
  resourceAreaHeaderDidMount() {
    // 添加拖动处理
    const header = document.querySelector('.fc-resource-area-header') as HTMLElement
    if (header) {
      header.style.cursor = 'col-resize'
      header.addEventListener('mousedown', (e: MouseEvent) => {
        const target = e.target as HTMLElement
        if (e.offsetX > target.offsetWidth - 10) {
          const startX = e.pageX
          const startWidth = target.offsetWidth

          function onMouseMove(e: MouseEvent) {
            const newWidth = startWidth + (e.pageX - startX)
            if (newWidth > 100) { // 最小宽度限制
              const resourceArea = document.querySelector('.fc-resource-area') as HTMLElement
              const resourceAreaContainer = document.querySelector('.fc-resource-area-container') as HTMLElement
              if (resourceArea && resourceAreaContainer) {
                resourceArea.style.width = `${newWidth}px`
                resourceAreaContainer.style.width = `${newWidth}px`
              }
            }
          }

          function onMouseUp() {
            document.removeEventListener('mousemove', onMouseMove)
            document.removeEventListener('mouseup', onMouseUp)
          }

          document.addEventListener('mousemove', onMouseMove)
          document.addEventListener('mouseup', onMouseUp)
        }
      })
    }
  },
  // 恢复分组功能
  resourceGroupField: 'officeBuildingName',
  resourceGroupLabelContent(arg) {
    // 移除排序前缀，只显示原始办公楼名称
    return arg.groupValue.replace(/^\d{2}_/, '')
  },
  // 确保资源顺序严格按数组顺序渲染，禁用FullCalendar的自动排序
  resourceOrder: null
})

const columns = [
  {
    title: '会议主题',
    dataIndex: 'title'
  },
  {
    title: '召集人',
    dataIndex: 'initiator'
  },
  {
    title: '部门',
    dataIndex: 'department',
    align: 'center'
  },
  {
    title: '会议类型',
    dataIndex: 'meetType',
    slotName: 'meetType'
  },
  {
    title: '会议地点',
    dataIndex: 'roomName',
    align: 'center'
  },
  {
    title: '开始时间',
    dataIndex: 'start',
    align: 'center'
  },
  {
    title: '结束时间',
    dataIndex: 'end',
    align: 'center'
  }
]
const tabledata = ref() // 会仪列表数据
// 创建自定义指令,监听资源组的滑动事件
const vResourceHover = {
  mounted(el: HTMLElement) {
    el.addEventListener('mouseenter', () => {
      el.classList.add('resource-hover')
    })
    el.addEventListener('mouseleave', () => {
      el.classList.remove('resource-hover')
    })
  }
}
/**
 * 日程今天按钮事件
 */
const todayToChange = () => {
  calendarApi.value.today()
  nextTick(() => {
    todayDate.value = calendarApi.value.currentData.viewTitle
    meetingRoomDataQuery.value.date = todayDate.value
    meetingRoomDataQuery.value.date = meetingRoomDataQueryDateFc(
      meetingRoomDataQuery.value.date
    )
    getMeetingRoomDataFc(factoryValue.value)

    // 检查当前视图，日视图禁止滑动
    if (calendarApi.value.view.type === 'resourceTimelineDay') {
      const timelineEl = document.querySelector('.fc-timeline-body')
      if (timelineEl) {
        (timelineEl as HTMLElement).style.overflowX = 'hidden'
      }
    }
  })
}
/**
 * 上一天
 */
const prevChange = () => {
  calendarApi.value.prev()
  nextTick(() => {
    todayDate.value = calendarApi.value.currentData.viewTitle
    meetingRoomDataQuery.value.date = todayDate.value
    meetingRoomDataQuery.value.date = meetingRoomDataQueryDateFc(
      meetingRoomDataQuery.value.date
    )
    getMeetingRoomDataFc(factoryValue.value)

    // 检查当前视图，日视图禁止滑动
    if (calendarApi.value.view.type === 'resourceTimelineDay') {
      const timelineEl = document.querySelector('.fc-timeline-body')
      if (timelineEl) {
        (timelineEl as HTMLElement).style.overflowX = 'hidden'
      }
    }
  })
}
/**
 * 下一天
 */
const nextChange = () => {
  calendarApi.value.next()
  nextTick(() => {
    todayDate.value = calendarApi.value.currentData.viewTitle
    meetingRoomDataQuery.value.date = todayDate.value
    meetingRoomDataQuery.value.date = meetingRoomDataQueryDateFc(
      meetingRoomDataQuery.value.date
    )
    getMeetingRoomDataFc(factoryValue.value)

    // 检查当前视图，日视图禁止滑动
    if (calendarApi.value.view.type === 'resourceTimelineDay') {
      const timelineEl = document.querySelector('.fc-timeline-body')
      if (timelineEl) {
        (timelineEl as HTMLElement).style.overflowX = 'hidden'
      }
    }
  })
}
/**
 * 年月日切换日程视图
 * @param: data：视图值
 */
const dateRadioGroupChange = (date) => {
  // 获取当前日期
  const currentDate = new Date()

  // 传入请求参数的type类型
  if (date === 'resourceTimelineDay') {
    meetingRoomDataQuery.value.type = 'day'
    // 获取当前日期，格式化为YYYY-MM-DD
    const year = currentDate.getFullYear()
    const month = String(currentDate.getMonth() + 1).padStart(2, '0')
    const day = String(currentDate.getDate()).padStart(2, '0')
    meetingRoomDataQuery.value.date = `${year}-${month}-${day}`

    // 先设置视图
    calendarApi.value.changeView(date)
    // 再设置日期
    calendarApi.value.gotoDate(currentDate)

    // 日视图禁止滑动
    const timelineEl = document.querySelector('.fc-timeline-body')
    if (timelineEl) {
      (timelineEl as HTMLElement).style.overflowX = 'hidden'
    }
  }
  if (date === 'resourceTimelineWeek') {
    meetingRoomDataQuery.value.type = 'week'
    // 获取当前日期
    const currentDate = new Date()
    // 先设置视图
    calendarApi.value.changeView(date)
    // 再设置日期
    // 获取本周一
    const day = currentDate.getDay() || 7 // 将周日的0转换为7
    const monday = new Date(currentDate)
    monday.setDate(currentDate.getDate() - (day - 1)) // 修正计算方式：当前日期减去(星期几-1)得到周一
    calendarApi.value.gotoDate(monday)

    // 传递今天的日期给后端
    const year = currentDate.getFullYear()
    const month = String(currentDate.getMonth() + 1).padStart(2, '0')
    const dayNum = String(currentDate.getDate()).padStart(2, '0')
    meetingRoomDataQuery.value.date = `${year}-${month}-${dayNum}`

    // 恢复周视图滑动
    const timelineEl = document.querySelector('.fc-timeline-body')
    if (timelineEl) {
      (timelineEl as HTMLElement).style.overflowX = 'auto'
    }
  }
  if (date === 'resourceTimelineMonth') {
    meetingRoomDataQuery.value.type = 'month'
    // 获取当前月份，只保留年月
    const year = currentDate.getFullYear()
    const month = String(currentDate.getMonth() + 1).padStart(2, '0')
    meetingRoomDataQuery.value.date = `${year}-${month}`

    // 先设置视图
    calendarApi.value.changeView(date)
    // 再设置日期到当前月份的第一天
    const firstDayOfMonth = new Date(currentDate.getFullYear(), currentDate.getMonth(), 1)
    calendarApi.value.gotoDate(firstDayOfMonth)

    // 恢复月视图滑动
    const timelineEl = document.querySelector('.fc-timeline-body')
    if (timelineEl) {
      (timelineEl as HTMLElement).style.overflowX = 'auto'
    }
  }

  // 获取数据
  getMeetingRoomDataFc(factoryValue.value)

  // 修正：切换视图后刷新todayDate为最新viewTitle
  nextTick(() => {
    if (calendarApi.value && calendarApi.value.currentData) {
      todayDate.value = calendarApi.value.currentData.viewTitle
    }
  })
}
/**
 * 新建会议弹窗标签卡切换事件
 */
const newMeetingTabsChange = async (value) => {
  meetingMessageValue.value = !meetingMessageValue.value
  // 等待子组件emit完成并更新meetingMessageFromData
  await nextTick()
  // 不再强制验证会议信息填写
}
/**
 * 分页网络请求
 */
const handlePageChange = (newPage: number) => {
  page.current = newPage
}
/**
 * 切换显示条数事件
 */
const handlePageSizeChange = (newSize: number) => {
  page.pageSize = newSize
  page.current = 1 // 切换每页条数后重置到第一页
}

/**
 * 获取表格数据
 */
const getTableFn = async () => {
  const res = await getMeetingRoomList({
    page: page.current,
    size: page.pageSize,
    meetType: 0,
    conferenceState: tableQuery.value.conferenceState,
    searchDate: tableQuery.value.searchDate
  })
  tabledata.value = res.data.list
  page.total = res.data.total
}
/**
 * 获取厂区列表
 */
const getFactoryListFc = async () => {
  const res = await getFactoryList()
  treeData.value = res.data.map((item) => ({
    key: item.id,
    title: item.name
  }))
}
/**
 * 获取办公楼
 */
const getSitebuildinglistFc = async () => {
  const res = await getSitebuildinglist()
  treeData.value = res.data.map((item) => ({
    key: item.id,
    title: item.name
  }))
}
/**
 * 厂区选择事件
 */
const sitebuildinglistTreeFc = (value: number) => {
  if (value) {
    factoryValue.value = value
    meetingRoomDataQuery.value.factoryId = value
    getMeetingRoomDataFc(value)
  }
}
/**
 * 获取会议室占用情况
 * @param factoryId 厂区id
 */
const getMeetingRoomDataFc = async (factoryId: number) => {
  if (factoryId) {
    // 清空现有数据
    meetingRoomList.value = []
    meetEventList.value = []
    tabledata.value = []
    page.total = 0
    page.current = 1

    function alignTo6HourBlock(dateStr, type) {
      const date = new Date(dateStr)
      const hour = date.getHours()
      const blockStart = Math.floor(hour / 6) * 6
      if (type === 'start') {
        date.setHours(blockStart, 0, 0, 0)
      } else {
        date.setHours(blockStart + 6, 0, 0, 0)
      }
      return date.toISOString()
    }

    // 新增：聚合会议数据（仅周/月视图）
    function groupMeetingsByBlock(events, type) {
      const blockMap = new Map()
      events.forEach((event) => {
        let blockStart, blockEnd
        if (type === 'week') {
          blockStart = alignTo6HourBlock(event.realStart, 'start')
          blockEnd = alignTo6HourBlock(event.realEnd, 'end')
        } else if (type === 'month') {
          const date = new Date(event.realStart)
          blockStart = new Date(date.getFullYear(), date.getMonth(), date.getDate()).toISOString()
          blockEnd = new Date(date.getFullYear(), date.getMonth(), date.getDate() + 1).toISOString()
        }
        const key = `${event.resourceId}_${blockStart}_${blockEnd}`
        if (!blockMap.has(key)) {
          blockMap.set(key, {
            resourceId: event.resourceId,
            roomName: event.roomName,
            start: blockStart,
            end: blockEnd,
            count: 0,
            meetings: []
          })
        }
        const block = blockMap.get(key)
        block.count += 1
        block.meetings.push(event)
      })
      return Array.from(blockMap.values())
    }

    try {
      const res = await getMeetingRoomData(meetingRoomDataQuery.value)
      if (!res.data || !Array.isArray(res.data)) {
        return
      }

      // 先按办公楼分组，再在每个组内按 roomSort 排序
      const grouped: Record<string, any[]> = {}
      res.data.forEach((item) => {
        const group = item.officeBuildingName || '未知楼宇'
        if (!grouped[group]) grouped[group] = []
        grouped[group].push(item)
      })

      // 对每个分组内的数据按 roomSort 排序，然后按楼宇名称排序后合并
      const sortedRooms = Object.keys(grouped)
        .sort() // 按楼宇名称排序
        .flatMap((groupName) =>
          grouped[groupName].sort((a, b) => {
            // 确保 roomSort 排序的稳定性
            const sortA = Number(a.roomSort ?? 0)
            const sortB = Number(b.roomSort ?? 0)
            if (sortA !== sortB) {
              return sortA - sortB
            }
            // 如果 roomSort 相同，按会议室名称排序作为备选
            return (a.roomName || '').localeCompare(b.roomName || '')
          })
        )

      // 为每个办公楼分组创建带排序的分组标识
      let groupIndex = 0
      const groupMap = new Map()

      const converted2 = sortedRooms.map((item) => {
        const { roomName, officeBuildingName, ...rest } = item

        // 为每个办公楼创建唯一的分组标识
        if (!groupMap.has(officeBuildingName)) {
          groupMap.set(officeBuildingName, groupIndex++)
        }

        const sortedGroupName = `${String(groupMap.get(officeBuildingName)).padStart(2, '0')}_${officeBuildingName}`

        return {
          title: `${officeBuildingName}-${roomName}`,
          officeBuildingName: sortedGroupName,
          originalOfficeBuildingName: officeBuildingName, // 保留原始办公楼名称
          roomName,
          roomSort: item.roomSort || 0, // 确保 roomSort 字段被保留
          ...rest
        }
      })

      // 调试输出：检查排序结果
      console.log('排序后的会议室列表:', converted2.map((room) => ({
        title: room.title,
        roomSort: room.roomSort,
        officeBuildingName: room.officeBuildingName
      })))

      // 确保最终传递给FullCalendar的资源顺序是按roomSort排序
      meetingRoomList.value = converted2

      // 过滤掉没有会议的会议室，并处理会议数据
      let result = meetingRoomList.value
        .filter((room) => room.occupancyPeriods && Array.isArray(room.occupancyPeriods) && room.occupancyPeriods.length > 0)
        .flatMap((room) =>
          room.occupancyPeriods
            .filter((period) => period && period.initiator && period.start && period.end)
            .map((period) => {
              const isWeek = meetingRoomDataQuery.value.type === 'week'
              const isMonth = meetingRoomDataQuery.value.type === 'month'
              return {
                ...period,
                resourceId: room.id,
                roomName: room.title,
                meetType: 0,
                realStart: period.start,
                realEnd: period.end,
                start: isWeek ? alignTo6HourBlock(period.start, 'start') : (isMonth ? (new Date(period.start).setHours(0, 0, 0, 0), new Date(period.start).toISOString()) : period.start),
                end: isWeek ? alignTo6HourBlock(period.end, 'end') : (isMonth ? (new Date(period.start).setHours(23, 59, 59, 999), new Date(period.start).toISOString()) : period.end)
              }
            })
        )
        .sort((a, b) => new Date(a.start).getTime() - new Date(b.start).getTime())

      // 聚合处理
      if (meetingRoomDataQuery.value.type === 'week' || meetingRoomDataQuery.value.type === 'month') {
        result = groupMeetingsByBlock(result, meetingRoomDataQuery.value.type)
        result = result.map((item) => ({
          ...item,
          title: String(item.count),
          extendedProps: { meetings: item.meetings }
        }))
      } else {
        result = result.map((item) => ({
          ...item,
          title: item.subject || item.title || '无主题',
          extendedProps: { ...item }
        }))
      }

      // 只有当有实际数据时才更新
      if (result && result.length > 0) {
        meetEventList.value = result
        tabledata.value = result.map((item) => {
          if (item.meetings) {
            // 聚合块，表格展示所有会议
            return item.meetings.map((m) => ({ ...m, start: m.realStart, end: m.realEnd }))
          } else {
            return { ...item, start: item.realStart, end: item.realEnd }
          }
        }).flat()
        page.total = tabledata.value.length
      }
    } catch (error) {
      console.error('获取会议室数据失败:', error)
      Message.error('获取会议室数据失败')
      tabledata.value = []
      page.total = 0
    }
  }
}
/**
 * 跳转预约会议页面
 */
const newMeeting = async () => {
  try {
    const res = await getCurrentUserInfo()
    if (res && res.success && res.data) {
      if (res.data.userid !== 'admin') {
        initialUserInfo.value = {
          realname: res.data.realname,
          userid: res.data.userid,
          avatar: res.data.avatar
        }
      } else {
        initialUserInfo.value = null
      }
    } else {
      initialUserInfo.value = null
    }
  } catch (e) {
    initialUserInfo.value = null
  }
  meetingType.value = 0
  newMeetingTabsKeyValue.value = '1'
  meetingMessageValue.value = false
  showMeetingMessage.value = false
  newMeetingModalVisible.value = true
  await nextTick()
  showMeetingMessage.value = true
}
/**
 * 服务会议表单回调事件
 */
const getMeetingServiceChange = (value) => {
  formQuery.value.serviceList = value.value
}
/**
 * 修改日期格式
 */
const meetingRoomDataQueryDateFc = (dateStr: string) => {
  if (meetingRoomDataQuery.value.type === 'week') {
    // 处理日期范围（支持中文破折号/全角横线/普通短横线）
    const rangeSplit = dateStr.split(/\s*[-–—]+\s*/) // 匹配所有横线类型
    if (rangeSplit.length > 1) {
      return meetingRoomDataQueryDateFc(rangeSplit[0]) // 仅处理左侧部分
    }
    // 主处理逻辑
    return dateStr
      .replace(/[年月日]/g, '-') // 替换中文符号
      .replace(/-+/g, '-') // 合并连续分隔符
      .replace(/-$/, '') // 去除末尾多余分隔符
      .split('-')
      .map((segment, index) => {
        if (index === 0) return segment // 年份不补零
        return segment.padStart(2, '0') // 月/日补零
      })
      .join('-')
  }
  // 主处理逻辑
  return dateStr
    .replace(/[年月日]/g, '-') // 替换中文符号
    .replace(/-+/g, '-') // 合并连续分隔符
    .replace(/-$/, '') // 去除末尾多余分隔符
    .split('-')
    .map((segment, index) => {
      if (index === 0) return segment // 年份不补零
      return segment.padStart(2, '0') // 月/日补零
    })
    .join('-')
}
/**
 * 接受会议信息回传的会议类型
 * @param value 会议信息回传的会议类型值
 */
const getMeetingTypeFc = (value) => {
  // 确保value是数字类型
  const typeValue = Number(value)
  // 验证值是否有效(0或1)
  if (typeValue === 0 || typeValue === 1) {
    meetingType.value = typeValue
    // 强制更新视图
    nextTick()
  } else {
    console.error('无效的会议类型值:', value)
    Message.error('会议类型设置失败')
  }
}
/**
 * 获取子组件的数据
 */
const getSonValue = (value) => {
  // meetingMessageFromData.value = value.value;
  // 获取会议信息表单后赋值给提交对象
  formQuery.value.meetingConfig.subject = value.subject
  formQuery.value.meetingConfig.startTime = value.startTime
  formQuery.value.meetingConfig.length = value.length
  formQuery.value.meetingConfig.mediaTypes = value.mediaTypes
  formQuery.value.meetingConfig.meetRoomId = value.meetRoomId
  formQuery.value.meetingConfig.meetType = value.meetType
  // 修正：将selectedUsers转换为attendees结构（userid字段）
  formQuery.value.meetingConfig.attendees = (value.selectedUsers || []).map((user) => ({
    userid: user.userid,
    appId: '9dbd6b334e744eada42b45b3bf6b8402'
  }))
  formQuery.value.meetingConfig.userId = value.treeUser
  formQuery.value.meetingConfig.signEndTime = '15'
  formQuery.value.meetingConfig.cycleParams = value.cycleParams
  formQuery.value.meetingConfig.confConfigInfo = value.confConfigInfo
  formQuery.value.meetingConfig.inviteScreen = value.inviteScreen
}
/**
 * 日期计算并转换范围内周几
 * @param startStr 开始日期
 * @param endStr 结束日期
 */
const getWeekDaysBetween = (startStr, endStr) => {
  // 解析日期字符串为本地时间的Date对象
  const parseDate = (dateStr) => {
    const [year, month, day] = dateStr.split('-').map(Number)
    return new Date(year, month - 1, day)
  }

  let startDate = parseDate(startStr)
  let endDate = parseDate(endStr)

  // 确保开始日期不晚于结束日期
  if (startDate > endDate) {
    [startDate, endDate] = [endDate, startDate]
  }

  const weekDaysSet = new Set()

  // 遍历每一天
  const currentDate = new Date(startDate.getTime())
  while (currentDate <= endDate) {
    const dayIndex = currentDate.getDay()
    // 直接使用getDay()返回值，周日为0
    weekDaysSet.add(dayIndex)
    currentDate.setDate(currentDate.getDate() + 1)
  }

  return Array.from(weekDaysSet)
}
/**
 * 根据周选择的数组判断是否在开始日期和结束日期内
 * @param daysArray 周选择的多选数组
 * @param startStr 开始时间
 * @param endStr 结束时间
 */
const datefiltrate = (daysArray, startStr, endStr) => {
  // 获取日期范围内的星期数字数组
  const weekDays = getWeekDaysBetween(startStr, endStr)
  // 将字符数组转换为数字数组（兼容字符串和数字混合输入）
  const targetDays = daysArray.map(Number)
  // 检查所有目标星期是否都存在于日期范围中
  return targetDays.every((day) => weekDays.includes(day))
}
/**
 *
 * @param daysArray 选择的月份中包含日的数组
 * @param startStr 开始时间
 * @param endStr 结束时间
 */
const monthScope = (daysArray, startStr, endStr) => {
  // 获取日期范围内的所有日（数字数组）
  const dateDays = getDaysBetween(startStr, endStr)

  // 将字符数组转换为数字数组（兼容字符串和数字混合输入）
  const targetDays = daysArray.map(Number)

  // 检查所有目标日是否都存在于日期范围中
  return targetDays.every(
    (day) =>
      Number.isInteger(day) // 过滤非数字
      && day >= 1
      && day <= 31 // 日期有效性验证
      && dateDays.includes(day)
  )
}
/**
 * 获取两个日期之间所有日期
 * @param startStr 开始日期
 * @param endStr 结束日期
 */
const getDaysBetween = (startStr, endStr) => {
  // 解析日期字符串为本地时间的Date对象
  const parseDate = (dateStr) => {
    const [year, month, day] = dateStr.split('-').map(Number)
    return new Date(year, month - 1, day)
  }

  let startDate = parseDate(startStr)
  let endDate = parseDate(endStr)

  // 确保开始日期不晚于结束日期
  if (startDate > endDate) {
    [startDate, endDate] = [endDate, startDate]
  }

  const days = []
  const currentDate = new Date(startDate.getTime())

  // 遍历每一天
  while (currentDate <= endDate) {
    days.push(currentDate.getDate()) // 获取当月第几天
    currentDate.setDate(currentDate.getDate() + 1) // 自动处理跨月
  }

  return days
}
/**
 * 会议签到页面表单回调
 */
const meetingSigninBackFc = (value) => {
  console.error('接收到子组件数据:', value)

  // 始终接收updateMethod值，无论是否为空字符串
  formQuery.value.meetingConfig.updateMethod = value.updateMethod

  formQuery.value.meetingConfig.backgroundImageURL = value.backgroundImageURL
  formQuery.value.meetingConfig.enableSignOut = value.enableSignOut
  formQuery.value.meetingConfig.signInBeforeMinutes = value.signInBeforeMinutes
  formQuery.value.meetingConfig.signOutAfterEndMinutes = value.signOutAfterEndMinutes
  formQuery.value.meetingConfig.signOutMinutesAfterSignIn = value.signOutMinutesAfterSignIn
  // 设置会议签到结束时间，默认为15分钟
  formQuery.value.meetingConfig.signEndTime = value.signInBeforeMinutes || '15'

  console.error('更新后的formQuery值:', formQuery.value.meetingConfig)
}
/**
 * 会务模板上传回调
 */
const onTemplateUploaded = (url) => {
  formQuery.value.meetingConfig.templateUrl = url
}
/**
 * 添加子组件引用
 */
const meetingMessageRef = ref()

/**
 * 重置所有表单内容
 */
const resetForm = () => {
  // 重置会议信息组件表单
  if (meetingMessageRef.value) {
    meetingMessageRef.value.resetForm()
  }

  // 重置formQuery对象
  formQuery.value = {
    meetingConfig: {
      userId: '', // 预定人userId
      subject: '', // 会议主题
      startTime: '', // 开始时间
      length: '', // 持续时间
      mediaTypes: '', // 媒体类型
      meetRoomId: '', // 会议室id
      meetType: '', // 会议类型 0 线下 1 线上
      signEndTime: '', // 会议签到结束时间
      enableSignOut: '', // 是否启用会议签退，0关闭，1开启
      signInBeforeMinutes: '', //	会议开始前多少分钟可以签到
      signOutMinutesAfterSignIn: '', // 会议签到多少分钟后才能签退
      signOutAfterEndMinutes: '', // 会议结束多少分钟后不能签退
      backgroundImageURL: null, // 图片链接
      updateMethod: '', // 更新方式：restoreDefault（恢复默认图片），single（单个图片更新），空（不更新）
      inviteScreen: 0, // 新增字段，默认不邀请
      templateUrl: '', // 会务模板URL
      confConfigInfo: {
        isGuestFreePwd: null, // 来宾是否免密
        callInRestriction: null, // 允许加入的会议范围 0：无限制 1：企业内部用户
        guestPwd: '', // 来宾密码
        enableWaitingRoom: null // 是否开启等候室
      },
      cycleParams: {
        startDate: '', // 开始日期 2025-02-25
        endDate: '', // 结束日期
        cycle: '', // 循环类型 Day，Week，Month
        interval: null, // 间隔时间 Integer
        point: [] // 周期点（如每周的哪些天）
      },
      attendees: []
    },
    serviceList: []
  }

  // 重置会议类型
  meetingType.value = 0

  // 重置标签页
  newMeetingTabsKeyValue.value = '1'
}
const isSubmitting = ref(false) // 新增：确定按钮 loading 状态
/**
 * 新建会议弹窗确认事件
 */
const handleOk = async () => {
  if (isSubmitting.value) return // 防止重复点击
  isSubmitting.value = true
  try {
    // 1. 触发子组件 emit 数据同步
    meetingMessageValue.value = !meetingMessageValue.value
    await nextTick()
    // 2. 表单前端校验（与会议日历页面一致）
    const config = formQuery.value.meetingConfig
    if (!config.subject || !config.subject.trim()) {
      Message.error('请输入会议主题')
      return
    }
    if (!config.startTime || !dayjs(config.startTime).isAfter(dayjs(), 'minute')) {
      Message.error('会议开始时间需大于当前时间')
      return
    }
    if (!config.userId) {
      Message.error('请选择预约人')
      return
    }
    if (!config.attendees || config.attendees.length === 0) {
      Message.error('请选择与会者')
      return
    }
    if (config.meetType === '0' && (!config.meetRoomId || config.meetRoomId.length === 0)) {
      Message.error('请选择会议室')
      return
    }
    // 3. 周期会议校验
    if (config.cycleParams && config.cycleParams.cycle) {
      if (config.cycleParams.cycle === 'Week') {
        const isDateScope = datefiltrate(
          config.cycleParams.point,
          config.cycleParams.startDate,
          config.cycleParams.endDate
        )
        if (isDateScope === false) {
          Message.error('请选择符合日期范围的星期')
          return
        }
      }
      if (config.cycleParams.cycle === 'Month') {
        const isDateScope = monthScope(
          config.cycleParams.point,
          config.cycleParams.startDate,
          config.cycleParams.endDate
        )
        if (isDateScope === false) {
          Message.error('请选择符合日期范围的日期')
          return
        }
      }
    }

    // 新增会议服务校验
    for (const [index, item] of (formQuery.value.serviceList || []).entries()) {
      if (item.serviceIds && item.serviceIds.length > 0 && (!item.userIds || item.userIds.length === 0)) {
        Message.error(`第${index + 1}项会议服务负责人未填写`)
        return
      }
      if (item.userIds && item.userIds.length > 0 && (!item.serviceIds || item.serviceIds.length === 0)) {
        Message.error(`第${index + 1}项会议服务项目未填写`)
        return
      }
    }
    // 4. 媒体类型处理（与会议日历页面一致）
    if (config.meetType === '1') {
      config.mediaTypes = 'HDVideo'
    } else if (!config.mediaTypes) {
      config.mediaTypes = 'HDVideo'
    }
    // 提交表单
    const res = await meetScheduledmeet(formQuery.value)
    if (res.success === true) {
      Message.success('会议预约成功')
      newMeetingModalVisible.value = false
      resetForm()
      // 只刷新会议室使用情况，不刷新整个页面
      getMeetingRoomDataFc(factoryValue.value)
    } else {
      Message.error('会议预约失败')
      newMeetingModalVisible.value = true
    }
  } finally {
    isSubmitting.value = false
  }
}
/**
 * 新建会议弹窗取消事件
 */
const handleCancel = () => {
  newMeetingModalVisible.value = false
}

/**
 * 更换门口屏图片
 */
const changeDoorScreenImage = () => {
  // 打开弹窗
  screenImageModalVisible.value = true
  // 获取厂区列表
  getFactorySiteList()
}

// 门口屏图片相关数据
const factorySiteList = ref([]) // 厂区列表
const buildingList = ref([]) // 办公楼列表
const floorList = ref([]) // 楼层列表
const roomList = ref([]) // 会议室列表
const selectedFactorySite = ref() // 选中的厂区
const selectedBuilding = ref() // 选中的办公楼
const selectedFloor = ref() // 选中的楼层
const selectedRoom = ref() // 选中的会议室
const uploadedImage = ref<string | null>(null) // 上传的图片
const imageFile = ref<File | null>(null) // 图片文件对象
const updateMethod = ref<string>('single') // 图片选项：restoreDefault（恢复默认）或single（单个更新）

// 获取厂区列表
const getFactorySiteList = async () => {
  try {
    const token = localStorage.getItem('token') || sessionStorage.getItem('token') || ''
    const res = await axios.get('/system/factorySite/factorySiteList', {
      headers: {
        Authorization: `Bearer ${token}`
      }
    })
    if (res.data && res.data.code === '0') {
      factorySiteList.value = res.data.data
    } else {
      Message.error('获取厂区列表失败')
    }
  } catch (error) {
    console.error('获取厂区列表错误:', error)
    Message.error('获取厂区列表失败')
  }
}

// 获取办公楼列表
const getBuildingList = async (factorySiteId) => {
  if (!factorySiteId) {
    buildingList.value = []
    return
  }
  try {
    const token = localStorage.getItem('token') || sessionStorage.getItem('token') || ''
    const res = await axios.get(`/system/meet/building?id=${factorySiteId}`, {
      headers: {
        Authorization: `Bearer ${token}`
      }
    })
    if (res.data && res.data.code === '0') {
      buildingList.value = res.data.data
      // 重置相关选择
      selectedBuilding.value = undefined
      selectedFloor.value = undefined
      selectedRoom.value = undefined
      floorList.value = []
      roomList.value = []
    } else {
      Message.error('获取办公楼列表失败')
    }
  } catch (error) {
    console.error('获取办公楼列表错误:', error)
    Message.error('获取办公楼列表失败')
  }
}

// 获取楼层列表
const getFloorList = async (buildingId) => {
  if (!buildingId) {
    floorList.value = []
    return
  }
  try {
    const token = localStorage.getItem('token') || sessionStorage.getItem('token') || ''
    const res = await axios.get(`/system/meet/availableFloor?buildingId=${buildingId}`, {
      headers: {
        Authorization: `Bearer ${token}`
      }
    })
    if (res.data && res.data.code === '0') {
      // 调整数据结构以匹配下拉框期望的格式
      floorList.value = res.data.data.map((item) => ({
        id: item.floor,
        name: item.floor
      }))
      // 重置相关选择
      selectedFloor.value = undefined
      selectedRoom.value = undefined
      roomList.value = []
    } else {
      Message.error('获取楼层列表失败')
    }
  } catch (error) {
    console.error('获取楼层列表错误:', error)
    Message.error('获取楼层列表失败')
  }
}

// 获取会议室列表
const getRoomList = async (floor) => {
  if (!floor) {
    roomList.value = []
    return
  }
  try {
    const token = localStorage.getItem('token') || sessionStorage.getItem('token') || ''
    const res = await axios.get(`/system/meetRoom/getFloorToRoom?floor=${floor}`, {
      headers: {
        Authorization: `Bearer ${token}`
      }
    })
    if (res.data && res.data.code === '0') {
      roomList.value = res.data.data
      // 重置相关选择
      selectedRoom.value = undefined
    } else {
      Message.error('获取会议室列表失败')
    }
  } catch (error) {
    console.error('获取会议室列表错误:', error)
    Message.error('获取会议室列表失败')
  }
}

// 厂区选择变更处理
const handleFactorySiteChange = (value) => {
  selectedFactorySite.value = value
  getBuildingList(value)
}

// 办公楼选择变更处理
const handleBuildingChange = (value) => {
  selectedBuilding.value = value
  getFloorList(value)
}

// 楼层选择变更处理
const handleFloorChange = (value) => {
  selectedFloor.value = value
  getRoomList(value)
}

// 会议室选择变更处理
const handleRoomChange = (value) => {
  selectedRoom.value = value
}

// 处理图片上传
const handleImageUpload = (event) => {
  const file = event.target.files?.[0]
  if (file) {
    imageFile.value = file
    const reader = new FileReader()
    reader.onload = (e) => {
      if (e.target) {
        uploadedImage.value = e.target.result as string
      }
    }
    reader.readAsDataURL(file)
  }
}

// 上传图片
const uploadImage = async () => {
  if (!selectedRoom.value) {
    Message.error('请选择会议室')
    return
  }

  if (updateMethod.value === 'single' && !imageFile.value) {
    Message.error('请上传图片')
    return
  }

  try {
    const token = localStorage.getItem('token') || sessionStorage.getItem('token') || ''

    // 不同的处理方式
    if (updateMethod.value === 'single') {
      // 先上传图片获取URL
      const formData = new FormData()
      if (imageFile.value) {
        formData.append('file', imageFile.value)
      }

      // 上传图片获取URL - 使用新接口
      const uploadRes = await axios.post('/user/file', formData, {
        headers: {
          'Content-Type': 'multipart/form-data',
          'Authorization': `Bearer ${token}`
        }
      })

      if (!uploadRes.data || uploadRes.data.code !== '0') {
        console.error('图片上传失败:', uploadRes.data)
        Message.error(uploadRes.data?.msg || '图片上传失败')
        return
      }

      // 获取上传后的图片URL
      const backgroundImageURL = uploadRes.data.data

      // 发送更新请求
      const res = await axios.post('/system/meet/changeDoorImg', {
        backgroundImageURL,
        updateMethod: 'single',
        roomId: selectedRoom.value
      }, {
        headers: {
          'Content-Type': 'application/json',
          'Authorization': `Bearer ${token}`
        }
      })

      if (res.data && res.data.code === '0') {
        Message.success('门口屏图片上传成功')
        screenImageModalVisible.value = false
        // 重置表单
        resetScreenImageForm()
      } else {
        console.error('门口屏图片设置失败:', res.data)
        Message.error(res.data?.msg || '门口屏图片上传失败')
      }
    } else {
      // 恢复默认图片
      const res = await axios.post('/system/meet/changeDoorImg', {
        updateMethod: 'restoreDefault',
        roomId: selectedRoom.value
      }, {
        headers: {
          'Content-Type': 'application/json',
          'Authorization': `Bearer ${token}`
        }
      })

      if (res.data && res.data.code === '0') {
        Message.success('已恢复默认门口屏图片')
        screenImageModalVisible.value = false
        // 重置表单
        resetScreenImageForm()
      } else {
        Message.error(res.data?.msg || '恢复默认图片失败')
      }
    }
  } catch (error) {
    console.error('上传图片错误:', error)
    Message.error('门口屏图片操作失败')
  }
}

// 重置门口屏图片表单
const resetScreenImageForm = () => {
  selectedFactorySite.value = undefined
  selectedBuilding.value = undefined
  selectedFloor.value = undefined
  selectedRoom.value = undefined
  uploadedImage.value = null
  imageFile.value = null
  buildingList.value = []
  floorList.value = []
  roomList.value = []
}

// 取消上传
const cancelUpload = () => {
  screenImageModalVisible.value = false
  resetScreenImageForm()
}

onMounted(() => {
  nextTick(() => {
    calendarApi.value = fullCalendar.value.getApi()
    todayDate.value = calendarApi.value.currentData.viewTitle
    // 设置默认日期为今天
    const today = new Date()
    const year = today.getFullYear()
    const month = String(today.getMonth() + 1).padStart(2, '0')
    const day = String(today.getDate()).padStart(2, '0')
    meetingRoomDataQuery.value.date = `${year}-${month}-${day}`
    meetingRoomDataQuery.value.type = 'day'
    // 设置默认厂区ID
    meetingRoomDataQuery.value.factoryId = 254
    // 获取厂区列表
    getFactoryListFc()
    // 触发厂区选择事件获取数据
    sitebuildinglistTreeFc(254)
    // 设置默认会议类型为线下(0)
    meetingType.value = 0

    // 默认日视图禁止滑动
    setTimeout(() => {
      const timelineEl = document.querySelector('.fc-timeline-body')
      if (timelineEl) {
        (timelineEl as HTMLElement).style.overflowX = 'hidden'
      }
    }, 500) // 延迟执行确保DOM已渲染
  })
})

// 计算当前页的数据
const currentPageData = computed(() => {
  if (!tabledata.value || !Array.isArray(tabledata.value)) {
    return []
  }
  const start = (page.current - 1) * page.pageSize
  const end = start + page.pageSize
  return tabledata.value.slice(start, end)
})

const showServiceTabs = computed(() => {
  return meetingType.value === 0 || (
    meetingType.value === 1
    && formQuery.value.meetingConfig.meetRoomId
    && formQuery.value.meetingConfig.meetRoomId.length > 0
  )
})
</script>

<template>
  <div style="padding: 1rem; overflow-y: scroll">
    <div style="display: flex; align-items: center">
      <a-image width="40" src="/logo.png" />
      <h3 style="margin-left: 10px">会议室使用情况</h3>
      <div
        style="display: flex; align-items: center; margin-left: 3rem; flex: 1"
      >
        <p>选择厂区：</p>
        <a-tree-select
          v-model="factoryValue"
          placeholder="请选择厂区"
          :data="treeData"
          style="
            width: 300px;
            margin-left: 10px;
            margin-top: 10px;
            margin-bottom: 10px;
            background-color: rgb(55, 136, 246);
            color: white;
          "
          size="medium"
          selectable="leaf"
          :field-names="{
            key: 'key',
            title: 'title',
            children: 'children',
          }"
          @change="sitebuildinglistTreeFc"
        />
        <a-button type="primary" style="margin-left: auto; margin-right: 12px" @click="newMeeting()"
          >
          会议室预约
</a-button
        >
        <a-button v-permission="['system:meetRoom:changeDoorImg']" type="primary" style="margin-right: 12px" @click="changeDoorScreenImage()"
          >
更换门口屏图片
</a-button
        >
      </div>
    </div>

    <div style="margin-top: 10px">
      <div class="demo-app">
        <div class="demo-app-main">
          <div
            style="
              display: flex;
              align-items: center;
              gap: 10px;
              padding: 0px 0px 10px 0px;
            "
          >
            <!-- <div><p>沈阳富创精密仪器设备有限公司</p></div> -->
            <div>
              <a-radio-group type="button" default-value="resourceTimelineDay">
                <a-radio
                  value="resourceTimelineDay"
                  @click="dateRadioGroupChange('resourceTimelineDay')"
                  >
日
</a-radio
                >
                <a-radio
                  value="resourceTimelineWeek"
                  @click="dateRadioGroupChange('resourceTimelineWeek')"
                  >
周
</a-radio
                >
                <a-radio
                  value="resourceTimelineMonth"
                  @click="dateRadioGroupChange('resourceTimelineMonth')"
                  >
月
</a-radio
                >
              </a-radio-group>
            </div>
            <div>
              <a-button type="text" @click="prevChange()">
                <template #icon>
                  <icon-left />
                </template>
              </a-button>
            </div>
            <div>{{ todayDate }}</div>
            <div>
              <a-button type="text" @click="nextChange()">
                <template #icon>
                  <icon-right />
                </template>
              </a-button>
            </div>
            <div>
              <a-button
                type="text"
                style="color: black"
                @click="todayToChange()"
              >
                今天
              </a-button>
            </div>
            <div style="display: flex; gap: 10px; margin-left: auto">
            </div>
          </div>
          <FullCalendar
            ref="fullCalendar"
            class="demo-app-calendar"
            :options="calendarOptions"
          >
            <!-- 添加自定义指令到资源单元格 -->
            <template #resourceLabelContent="arg">
              <a-popover trigger="hover" position="right">
                <div>
                  <div
                    v-resource-hover
                    class="custom-resource-cell"
                    :data-resource-id="arg.resource.id"
                  >
                    {{ arg.resource.title }}
                  </div>
                </div>
                <!-- Popover 弹层内容 -->
                <template #content>
                  <!-- 这里可以自由组合弹层内容 -->
                  <div>
                    <a-image
                      width="200"
                      :src="arg.resource.extendedProps.avatar"
                    />
                    <div style="margin-top: 10px; display: flex">
                      <p style="font-weight: bold">会议室名称：</p>
                      <p>{{ arg.resource.title }}</p>
                    </div>
                    <div style="margin-top: 10px; display: flex">
                      <p style="font-weight: bold">容量：</p>
                      <p>{{ arg.resource.extendedProps.capacity }}</p>
                    </div>
                    <div style="margin-top: 10px; display: flex">
                      <p style="font-weight: bold">会议室设备：</p>
                      <p>{{ arg.resource.extendedProps.equipment }}</p>
                    </div>
                  </div>
                </template>
              </a-popover>
            </template>
            <!-- 日程的插槽内容 -->
            <template #eventContent="arg">
              <a-popover trigger="hover" position="bl">
                <div style="width: 100%; height: 100%; display: flex; align-items: center; justify-content: center;">
                  <span v-if="['resourceTimelineWeek', 'resourceTimelineMonth'].includes(arg.view.type)"
                        style="color: #fff; font-size: 20px; font-weight: bold;">
                    <!-- 强制显示聚合数量 -->
                    {{ (arg.event.extendedProps && arg.event.extendedProps.meetings) ? arg.event.extendedProps.meetings.length : arg.event.title }}
                  </span>
                  <span v-else
                    style="max-width: 120px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; display: inline-block;"
                  >
                    {{ arg.event.title || (arg.event.extendedProps && arg.event.extendedProps.subject) || '无主题' }}
                  </span>
                </div>
                <template #content>
                  <div v-if="['resourceTimelineWeek', 'resourceTimelineMonth'].includes(arg.view.type)"
                       style="max-height: 300px; overflow-y: auto; min-width: 220px;">
                    <div v-for="(meeting, idx) in arg.event.extendedProps.meetings" :key="idx" style="margin-bottom: 8px;">
                      <i>{{ meeting.title }}</i>
                      <p>预约人: {{ meeting.initiator }}</p>
                      <p>部门: {{ meeting.department || '暂无' }}</p>
                      <p>与会人: {{ meeting.guest }}</p>
                      <p>开始时间: {{ new Date(meeting.realStart).toLocaleString('zh-CN') }}</p>
                      <p>结束时间: {{ new Date(meeting.realEnd).toLocaleString('zh-CN') }}</p>
                      <p>手机号: {{ meeting.phone }}</p>
                      <hr v-if="idx !== arg.event.extendedProps.meetings.length - 1" />
                    </div>
                  </div>
                  <div v-else>
                    <i>{{ arg.event.title }}</i>
                    <p>预约人: {{ arg.event.extendedProps.initiator }}</p>
                    <p>部门: {{ arg.event.extendedProps.department || '暂无' }}</p>
                    <p>与会人: {{ arg.event.extendedProps.guest }}</p>
                    <p>开始时间: {{ arg.event.extendedProps.realStart ? new Date(arg.event.extendedProps.realStart).toLocaleString('zh-CN') : '' }}</p>
                    <p>结束时间: {{ arg.event.extendedProps.realEnd ? new Date(arg.event.extendedProps.realEnd).toLocaleString('zh-CN') : '' }}</p>
                    <p>手机号: {{ arg.event.extendedProps.phone }}</p>
                  </div>
                </template>
              </a-popover>
            </template>

            <template #resourceContent="arg">
              <div>1111</div>
              {{ arg.event }}
            </template>
          </FullCalendar>
        </div>
      </div>
    </div>
    <div>
      <a-table
        :columns="columns"
        :data="currentPageData"
        :pagination="false"
        :loading="false"
        :empty="{
          description: '暂无数据',
        }"
      >
        <!-- 会议类型列插槽 -->
        <template #meetType="{ record }">
          <p>线下</p>
        </template>
      </a-table>
    </div>
    <div style="margin-left: auto; display: flex; justify-content: flex-end">
      <!-- 添加分页器 -->
      <a-pagination
        v-model:current="page.current"
        v-model:page-size="page.pageSize"
        :total="page.total"
        :show-total="page.showTotal"
        :show-jumper="page.showJumper"
        :page-size-options="[5, 10, 20, 50]"
        :show-page-size="true"
        style="margin-top: 16px"
        @change="handlePageChange"
        @page-size-change="handlePageSizeChange"
      />
    </div>

    <a-modal
      v-model:visible="newMeetingModalVisible"
      title-align="start"
      width="850px"
      :modal-style="{ maxHeight: '80vh' }"
      :body-style="{ padding: '0', maxHeight: 'calc(80vh - 100px)', overflow: 'hidden' }"
      @cancel="handleCancel"
    >
      <template #title> 新建会议 </template>
      <div class="tabs-container">
        <a-tabs
          v-model:active-key="newMeetingTabsKeyValue"
          default-active-key="1"
          class="fixed-tabs"
          @change="newMeetingTabsChange"
        >
          <a-tab-pane key="1" title="会议信息">
            <div class="tabs-content">
              <meetingMessage
                v-if="showMeetingMessage"
                ref="meetingMessageRef"
                :type="meetingMessageValue"
                :initial-user-info="initialUserInfo"
                @get-value="getSonValue"
                @get-meeting-type="getMeetingTypeFc"
              />
            </div>
          </a-tab-pane>
          <a-tab-pane v-if="showServiceTabs" key="3">
            <template #title>会议服务</template>
            <div class="tabs-content">
              <meetingService
                :type="meetingMessageValue"
                @get-meeting-service-form-value="getMeetingServiceChange"
              />
            </div>
          </a-tab-pane>
          <a-tab-pane v-if="showServiceTabs" key="4">
            <template #title>会议签到</template>
            <div class="tabs-content">
              <meetingSignln
                :type="meetingMessageValue"
                @meeting-signin-fc="meetingSigninBackFc"
              />
            </div>
          </a-tab-pane>
          <a-tab-pane v-if="showServiceTabs" key="5">
            <template #title>会务模板</template>
            <div class="tabs-content">
              <meetingTemplate @template-uploaded="onTemplateUploaded" />
            </div>
          </a-tab-pane>
        </a-tabs>
      </div>
      <template #footer>
        <a-button @click="handleCancel">取消</a-button>
        <a-button type="primary" :loading="isSubmitting" :disabled="isSubmitting" @click="handleOk">确定</a-button>
      </template>
    </a-modal>

    <!-- 更换门口屏图片弹窗 -->
    <a-modal
      v-model:visible="screenImageModalVisible"
      title-align="start"
      width="800px"
      :modal-style="{ maxHeight: '80vh' }"
      :body-style="{ padding: '16px', maxHeight: 'calc(80vh - 100px)', overflow: 'auto' }"
      @ok="uploadImage"
      @cancel="cancelUpload"
    >
      <template #title>更换门口屏图片</template>
      <div>
        <a-form :model="{}">
          <a-form-item label="选择厂区">
            <a-select
              v-model="selectedFactorySite"
              placeholder="请选择厂区"
              style="width: 100%"
              :popup-max-height="300"
              @change="handleFactorySiteChange"
            >
              <a-option
                v-for="site in factorySiteList"
                :key="site.id"
                :value="site.id"
              >
                {{ site.name }}
              </a-option>
            </a-select>
          </a-form-item>

          <a-form-item label="选择办公楼">
            <a-select
              v-model="selectedBuilding"
              placeholder="请先选择厂区"
              style="width: 100%"
              :disabled="!selectedFactorySite"
              :popup-max-height="300"
              @change="handleBuildingChange"
            >
              <a-option
                v-for="building in buildingList"
                :key="building.id"
                :value="building.id"
              >
                {{ building.name }}
              </a-option>
            </a-select>
          </a-form-item>

          <a-form-item label="选择楼层">
            <a-select
              v-model="selectedFloor"
              placeholder="请先选择办公楼"
              style="width: 100%"
              :disabled="!selectedBuilding"
              :popup-max-height="300"
              @change="handleFloorChange"
            >
              <a-option
                v-for="floor in floorList"
                :key="floor.id"
                :value="floor.id"
              >
                {{ floor.name }}
              </a-option>
            </a-select>
          </a-form-item>

          <a-form-item label="选择会议室">
            <a-select
              v-model="selectedRoom"
              placeholder="请先选择楼层"
              style="width: 100%"
              :disabled="!selectedFloor"
              :popup-max-height="300"
              @change="handleRoomChange"
            >
              <a-option
                v-for="room in roomList"
                :key="room.id"
                :value="room.id"
              >
                {{ room.name }}
              </a-option>
            </a-select>
          </a-form-item>

          <a-form-item label="上传图片">
            <div>
              <a-radio-group v-model="updateMethod">
                <a-radio value="single">上传自定义图片</a-radio>
                <a-radio value="restoreDefault">恢复默认图片</a-radio>
              </a-radio-group>
            </div>
            <div v-if="updateMethod === 'single'" style="margin-top: 10px;">
              <input
                type="file"
                accept="image/*"
                @change="handleImageUpload"
              />
              <div style="margin-top: 5px; color: #666; font-size: 12px;">
                请上传小于2M，分辨率1280*800大小的图片，以获得最佳显示效果
              </div>
            </div>
          </a-form-item>

          <a-form-item v-if="uploadedImage && updateMethod === 'single'" label="图片预览">
            <img :src="uploadedImage" style="max-width: 100%; max-height: 300px;" />
          </a-form-item>
        </a-form>
      </div>
    </a-modal>
  </div>
</template>

<style>
 .fc .fc-datagrid-cell-cushion {
  display: flex;
  justify-content: center;
  align-items: center;
}
/* 隐藏fc-datagrid-expander和fc-datagrid-expander-placeholder类的DOM */
 .fc-datagrid-expander,
.fc-datagrid-expander-placeholder {
  display: none !important;
}
/* .fc-datagrid-cell {
  display: flex;
  justify-content: center;
  align-items: center;
} */
 .fc .fc-timeline-header-row-chrono .fc-timeline-slot-frame {
  width: 100%;
  justify-content: center !important;
}
/*
.fc td {
  height: 34px;
} */
/* 修改日历组件的基础样式 */
.demo-app {
  display: flex;
  font-family: Arial, Helvetica Neue, Helvetica, sans-serif;
  font-size: 14px;
  height: 100%;
}

.demo-app-main {
  flex: 1;
  min-width: 0;
  overflow-x: auto;
  height: 100%;
}

/* 修改资源区域（左侧会议室列表）的样式 */
:deep(.fc-resource-area) {
  min-width: 200px !important;
  width: 200px !important;
  flex-shrink: 0 !important;
  background-color: #fff !important;
  border-right: 1px solid #ddd !important;
}

/* 修改资源单元格的样式 */
:deep(.fc-resource-area .fc-datagrid-cell-main) {
  padding: 0 4px !important;
  white-space: nowrap !important;
  overflow: hidden !important;
  text-overflow: ellipsis !important;
  height: 12px !important;
  line-height: 12px !important;
  font-size: 11px !important;
}

/* 修改资源区域的单元格样式 */
:deep(.fc-resource-area .fc-datagrid-cell) {
  padding: 0 !important;
  border-right: 1px solid #ddd !important;
  width: 200px !important;
  height: 12px !important;
}

/* 修改表头单元格的样式 */
:deep(.fc-resource-area .fc-datagrid-header-cell) {
  padding: 0 4px !important;
  height: 12px !important;
  line-height: 12px !important;
  font-size: 11px !important;
}

/* 修改资源区域表格的样式 */
:deep(.fc-resource-area .fc-datagrid-body) {
  height: auto !important;
}

:deep(.fc-resource-area .fc-datagrid-body tr) {
  height: 12px !important;
}

:deep(.fc-resource-area .fc-datagrid-body td) {
  height: 12px !important;
  padding: 0 !important;
}

/* 修改资源区域容器的样式 */
:deep(.fc-resource-area-container) {
  min-width: 200px !important;
  width: 200px !important;
  flex-shrink: 0 !important;
  border-right: 1px solid #ddd !important;
  height: auto !important;
}

/* 修改表格样式 */
:deep(.a-table) {
  margin-top: 10px;
}

:deep(.a-table th),
:deep(.a-table td) {
  padding: 2px 4px !important;
  height: 20px !important;
  line-height: 16px !important;
  font-size: 11px !important;
}

:deep(.a-table .a-table-header) {
  height: 20px !important;
  line-height: 16px !important;
  font-size: 11px !important;
}

/* 修改日历事件样式 */
:deep(.fc-event) {
  margin: 0 !important;
  padding: 0 !important;
  height: 12px !important;
  line-height: 12px !important;
  font-size: 11px !important;
  cursor: default !important;
  pointer-events: none !important;
  min-width: 0 !important; /* 新增，允许事件块最小宽度为0，防止短会议错位 */
}

:deep(.fc-event-main) {
  padding: 0 2px !important;
  height: 12px !important;
  line-height: 12px !important;
}

:deep(.fc-timeline-slot) {
  height: 12px !important;
  line-height: 12px !important;
}

:deep(.fc-timeline-slot-frame) {
  height: 12px !important;
  line-height: 12px !important;
  font-size: 11px !important;
}

/* 添加资源区域拖动样式 */
:deep(.fc-resource-area-header) {
  position: relative;
  cursor: col-resize;
}

:deep(.fc-resource-area-header::after) {
  content: '';
  position: absolute;
  right: 0;
  top: 0;
  bottom: 0;
  width: 5px;
  background-color: transparent;
  cursor: col-resize;
}

:deep(.fc-resource-area-header:hover::after) {
  background-color: #e8e8e8;
}

/* 月视图横轴标签样式 - 只显示数字 */
:deep(.fc-resourceTimelineMonth .fc-timeline-slot-label) {
  font-size: 11px !important;
  text-align: center !important;
}

/* 确保月视图只显示日期数字，不显示"日"字 */
:deep(.fc-resourceTimelineMonth .fc-timeline-slot-label) {
  text-align: center !important;
}

/* 强制月视图标签只显示数字 */
:deep(.fc-resourceTimelineMonth .fc-timeline-slot-label) {
  &::after {
    content: none !important;
  }
}
:deep(.arco-modal) {
  max-height: 80vh;
}

:deep(.arco-modal-content) {
  max-height: 80vh;
  display: flex;
  flex-direction: column;
}

:deep(.arco-modal-body) {
  flex: 1;
  overflow: auto;
  padding: 0;
}

.tabs-container {
  display: flex;
  flex-direction: column;
  height: 100%;
}

.fixed-tabs {
  position: sticky;
  top: 0;
  z-index: 10;
  background-color: #fff;
  border-bottom: 1px solid #e8e8e8;
}

.tabs-content {
  padding: 16px;
  overflow-y: auto;
  max-height: calc(80vh - 180px);
}

:deep(.arco-tabs-nav) {
  margin-bottom: 0;
}

:deep(.arco-tabs-content) {
  height: 100%;
  overflow: visible;
}

:deep(.fc-timeline-slot-label),
:deep(.fc-timeline-slot-label-frame) {
  text-align: center !important;
  font-size: 12px !important;
  font-weight: 500;
}

:deep(.fc-resource-area .fc-datagrid-header-cell) {
  text-align: center !important; /* 确保纵轴标签居中 */
}

/* 样式补充，兜底居中 */
:deep(.a-table td),
:deep(.a-table th) {
  text-align: center !important;
}
.center-cell {
  text-align: center;
  width: 100%;
  display: block;
}
</style>
